package main

import (
	"log"
	"net"
	"net/http"
	"os/exec"
	"strings"
	"sync"

	"github.com/energye/systray"
	"github.com/energye/systray/icon"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"gopkg.in/mgo.v2"
)

type Device struct {
	ip   string
	conn net.Conn
}

var ips map[string]Device
var lock sync.Mutex
var Session *mgo.Session

func main() {
	go func() {
		listener, err := net.Listen("tcp", ":10001")
		if err != nil {
			log.Println(err)
			return
		}
		defer listener.Close()
		for {
			conn, err := listener.Accept()
			if err != nil {
				log.Println(err)
				continue
			}

			log.Println("connect:", conn.RemoteAddr())
			go func(conn net.Conn) {
				defer conn.Close()
				buf := make([]byte, 45)
				for {
					n, err := conn.Read(buf)
					if err != nil {
						log.Println(conn.RemoteAddr(), err)
						return
					}
					item := strings.Split(string(buf[:n]), "#")
					if len(item) == 2 {
						lock.Lock()
						if _, err := ips[item[0]]; !err {
							ips[item[0]] = Device{conn.RemoteAddr().Network(), conn}
						}
						lock.Unlock()
					}
				}
			}(conn)
		}
	}()
	go func() {
		pc, err := net.ListenPacket("udp", ":10002")
		if err != nil {
			log.Println(err)
			return
		}
		defer pc.Close()
		buffer := make([]byte, 1024)
		for {
			n, addr, err := pc.ReadFrom(buffer)
			if err != nil {
				log.Println(err)
				continue
			}
			log.Println("udp receive ", addr.Network(), n)
		}
	}()
	go func() {
		engine := HttpServer()
		engine.POST("/connect", func(c *gin.Context) {
			result := []bson.M{}
			collection := Session.DB("remote").C("device")
			item := bson.M{"code": c.PostForm("code"), "password": c.c.PostForm("password")}
			err := collection.Find(item).One(&result)
			if err == nil {
				lock.Lock()
				if _, err := ips[result]; !err {

				}
				lock.Unlock()
			} else {
				c.JSON(http.StatusOK, gin.H{"msg": err.Error(), "data": result})
			}
		})
		engine.Run()
	}()
	systray.Run(func() {
		systray.SetTitle("App")
		systray.SetIcon(icon.Data)
		systray.SetTooltip("App Test")
		open := systray.AddMenuItem("Open", "Open the application")
		quit := systray.AddMenuItem("Quit", "Quit the application")
		systray.SetOnDClick(func(menu systray.IMenu) {
			exec.Command("cmd.exe", "/c", "start http://localhost:8080").Run()
		})
		systray.SetOnRClick(func(menu systray.IMenu) {
			menu.ShowMenu()
		})
		open.Click(func() {
			exec.Command("cmd.exe", "/c", "start http://localhost:8080").Run()
		})
		quit.Click(func() {
			systray.Quit()
		})
	}, nil)
}
